/* Prezentowany poniej program-klient suy do pobierania zawartoci       */
/* pliku o wskazanej nazwie z serwera o wskazanym adresie internetowym.     */
/* W odpowiedzi na danie serwer przesya jednorazowo ca zawarto pliku */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define SERVER_PORT 12345	/* warto wybrana arbitralnie, musi by jednakowa */
                                /* dla klienta i serwera */
#define BUF_SIZE 4096		/* wielkos porcji przesyania danych */

int main(int argc, char **argv)
{
  int c, s, bytes;
  char buf[BUF_SIZE];			/* bufor dla przesyanej zawartoci */
  struct hostent *h;			/* zawiera informacj o serwerze */
  struct sockaddr_in channel;		/* zawiera adres IP serwera */

  if (argc != 3) fatal("Wywoanie: client <nazwa serwera> <nazwa pliku>");
  h = gethostbyname(argv[1]);		/* uzyskiwanie adresu IP serwera */
                                        /* na podstawie jego nazwy      */
  if (!h) fatal("nie mona uzyska adresu IP serwera");

  s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (s < 0) fatal("nie mona utworzy gniazda");
  memset(&channel, 0, sizeof(channel));
  channel.sin_family= AF_INET;
  memcpy(&channel.sin_addr.s_addr, h->h_addr, h->h_length);
  channel.sin_port= htons(SERVER_PORT);
  c = connect(s, (struct sockaddr *) &channel, sizeof(channel));
  if (c < 0) fatal("nie powiodo si wywoanie funkcji connect");

  /* Poczenie zostalo nazwizane */
  /* Przesanie nazwy pliku zakoczonej zerowym ogranicznikiem */
  write(s, argv[2], strlen(argv[2])+1);

  /* odczytywanie zawartoci pliku i wypisywanie jej na standardowe wyjcie */
  while (1) {
        bytes = read(s, buf, BUF_SIZE);	/* czytaj porcj z gniazda */
        if (bytes <= 0) exit(0);	        /* sprawd, czy nie koniec pliku */
        write(1, buf, bytes);		        /* wypisz porcj na standardowe wyjcie */
  }
}

fatal(char *string)
{
  printf("%s\n", string);
  exit(1);
}

